var ImageDataHelper = {
	getIndex: function(w, x, y){
		return (w * y + x) * 4;
	},
	each: function(ctx, fn, x, y, w, h){
		x = x || 0;
		y = y || 0;
		w = w || ctx.canvas.width;
		h = h || ctx.canvas.height;
		w = Math.min(w, ctx.canvas.width);
		h = Math.min(h, ctx.canvas.height);
		var img = ctx.getImageData(x, y, w, h);
		var len = img.data.length, i = 0;
			console.log(img)
		var color = [], idx;
		for(; i < len; i += 4){
			idx = i / 4;
			x = idx % img.width;
			y = (idx / img.width) >> 0;
			color[0] = img.data[i + 0];
			color[1] = img.data[i + 1];
			color[2] = img.data[i + 2];
			color[3] = img.data[i + 3];
			if(fn(i, x, y, color)){
				return;
			}
		}
	},
	eachData: function(data, fn){
		var len = data.length, i = 0, c = [];
		for(; i < len; i += 4){
			c[0] = data[i + 0];
			c[1] = data[i + 1];
			c[2] = data[i + 2];
			c[3] = data[i + 3];
			if(fn(c, i)){
				return;
			}
		}
	},
	eachBlock: function(ctx, fn, w, h){
		h = h || w;
		for(var j = 0; j < ctx.canvas.height; j += h){
			for(var i = 0; i < ctx.canvas.width; i += w){
				var img = ctx.getImageData(i, j, w, h);
				if(fn(img, i / w, j / h)){
					break;
				}
			}
		}
	},
	findBorder: function(imgData, colorHandle){
		var w = imgData.width, idx, color = [];
		var previous, result = [], hash, c, p, _p, k;

		var id_helper = {};
		var key_helper = {};

		previous = undefined;
		for(var y = 0; y < imgData.height; y++){
			c = 0;
			for(var x = 0; x < imgData.width; x++){
				idx = (x + y * w) * 4;
				color[0] = imgData.data[idx + 0];
				color[1] = imgData.data[idx + 1];
				color[2] = imgData.data[idx + 2];
				color[3] = imgData.data[idx + 3];
				hash = colorHandle(color, x, y, idx / 4);
				if(hash != previous){
					if(previous != undefined){
						p = { id: idx / 4, x: x, y: y };
						if(c % 2 === 1){
							p.x -= 1;
						}
						result.push(p);
						key_helper[p.x + '_' + p.y] = id_helper[p.id] = result.length - 1;
					}
				}
				previous = hash;
			}
		}
		previous = undefined;
		for(var x = 0; x < imgData.width; x++){
			c = 0;
			for(var y = 0; y < imgData.height; y++){
				idx = (x + y * w) * 4;
				color[0] = imgData.data[idx + 0];
				color[1] = imgData.data[idx + 1];
				color[2] = imgData.data[idx + 2];
				color[3] = imgData.data[idx + 3];
				hash = colorHandle(color, x, y, idx / 4);
				if(hash != previous){
					if(previous != undefined){
						p = { id: idx / 4, x: x, y: y };
						if(c % 2 === 1){
							p.x -= 1;
						}
						k = p.x + '_' + p.y;
						if(k in result){
							result[k].cr = 1;
						} else {
							result.push(p);
							key_helper[k] = id_helper[p.id] = result.length - 1;
						}
					}
				}
				previous = hash;
			}
		}

		result.getByPosition = function(x, y){
			return this.getByKey(x + '_' + y);
		};
		result.getIndexByKey = function(key){
			return key in key_helper ? key_helper[key] : -1;
		};
		result.getIndexId = function(id){
			return id in id_helper ? id_helper[id] : -1;
		};
		result.getByKey = function(key){
			return this[key_helper[key]];
		};
		result.getById = function(id){
			var idx = this.getIndexId(id);
			return idx > -1 ? this[idx] : null;
		};
		result.getIdByKey = function(key){
			var idx = this.getIndexByKey(key);
			return idx < 0 ? null : this[idx].id;
		};

		// result.setElement = function(idx, fn){
		// 	if(idx in result){
		// 		fn(result[idx]);
		// 	}
		// };


		return result;
	},
	/*
	1	2	3
	8	O	4
	7	6	5
	 */
	pointConnectType: function(O, P){
		if(O.x == P.x && O.y == P.y) return 0;
		else if(Math.abs(O.x - P.x) > 1 || Math.abs(O.y - P.y) > 1) return -1;
		if(O.x == P.x){
			return O.y > P.y ? 2 : 6;
		} else if(O.x > P.x) {
			return O.y > P.y ? 1 : O.y < P.y ? 7 : 8;
		} else {
			return O.y > P.y ? 3 : O.y < P.y ? 5 : 4;
		}
	},
	createConnectIndex: function(o){
		var r = [];
		//1
		r.push((o.x - 1) + '_' + (o.y - 1));
		//2
		r.push((o.x) + '_' + (o.y - 1));
		//3
		r.push((o.x + 1) + '_' + (o.y - 1));
		//4
		r.push((o.x + 1) + '_' + (o.y));
		//5
		r.push((o.x + 1) + '_' + (o.y + 1));
		//6
		r.push((o.x) + '_' + (o.y + 1));
		//7
		r.push((o.x - 1) + '_' + (o.y + 1));
		//8
		r.push((o.x - 1) + '_' + (o.y));
		return r;
	},
	findConnectedPoint: function(arr, o){
		return arr.filter(function(p){
			return ImageDataHelper.pointConnectType(o, p) > 0;
		});
	}
};